/*
Dijjer - A Peer to Peer HTTP Cache
Copyright (C) 2004,2005  Change.Tv, Inc

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

package dijjer.util;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.jar.JarFile;
import dijjer.util.logging.Logger;

public class Version {

	public static final String VERSION = "$Id: Version.java 2 2008-03-21 14:33:03Z ian.clarke $";

	public static void printVersions() {

		Set classeNames = findClassesInPath(System.getProperty("java.class.path"));
		for (Iterator i = classeNames.iterator(); i.hasNext();) {
			String className = (String) i.next();
			if (className.indexOf("dijjer") >= 0 && className.indexOf('$') < 0) {
				try {
					Class dijClass = Version.class.getClassLoader().loadClass(className) ;
					Field field = dijClass.getField("VERSION");
					field.setAccessible(true);
					//note, intentionally not using the logger here.  This message id for debugging and
					//must work even if the logger is completely broken.
					System.out.println(className + " - " + field.get(null));
				} catch (NoSuchFieldException e) {
					System.out.println(className + " - NO VERSION");
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	private static final Set findClassesInPath(String path) {
		Set classes = new HashSet();
		StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
		while (st.hasMoreTokens()) {
			ArrayList ret = new ArrayList();
			File dir = new File(st.nextToken());
			if (dir.isDirectory()) {
				ret.addAll(walkDir(dir));
			} else if (dir.isFile() && dir.getName().endsWith(".jar")) {
				try {
					ret.addAll(walkJar(dir));
				} catch (IOException e) {
					Logger.error("Can't open: " + dir);
				}
			} else {
				if (dir.getName().endsWith(".class")) {
					ret.add(dir.getAbsolutePath().substring(0,
					    dir.getAbsolutePath().length() - ".class".length()));
				}
			}
			if (!ret.isEmpty()) {
				boolean isJar = dir.getAbsolutePath().endsWith(".jar");
				for (Iterator i = ret.iterator(); i.hasNext();) {
					String cfile = (String) i.next();
					if (!isJar) {
						cfile = cfile.substring(dir.getAbsolutePath().length() + 1);
					}
					classes.add(cfile.replace('\\', '.').replace('/', '.'));
				}
			}
		}
		return classes;
	}

	private static final List walkDir(File dir) {
		ArrayList ret = new ArrayList();
		File[] dirs = dir.listFiles();
		for (int i = 0; i < dirs.length; i++) {
			if (dirs[i].isDirectory()) {
				ret.addAll(walkDir(dirs[i]));
			} else if (dirs[i].getName().endsWith(".class")) {
				final String dirpath = dirs[i].getAbsolutePath();
				ret.add(dirpath.substring(0, dirpath.length() - ".class".length()));
			}
		}
		return ret;
	}

	private static final List walkJar(File jar) throws IOException {
		ArrayList ret = new ArrayList();
		Enumeration en = new JarFile(jar).entries();
		while (en.hasMoreElements()) {
			String entryname = en.nextElement().toString();
			if (entryname.endsWith(".class")) {
				ret.add(entryname.substring(0, entryname.length() - ".class".length()));
			}
		}
		return ret;
	}

}

